/*
 * Copyright (C) 2012-2013 Matthias Zeimer and the miniframes project group.
 * All rights reserved. 
 * 
 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.opensource.org/licenses/EPL-1.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.miniframes.minivalues;

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

/**
 * <p>
 * A value version of a {@link Timestamp} of {@link Date}. This Date kind is
 * unmodifiable.
 * </p>
 * 
 * <p>
 * TODO Change to work with {@link Timestamp} instead of Date (nanoseconds
 * support) and use timestamps toString-format.
 * </p>
 * 
 * <p>
 * TODO TEST & Doc
 * </p>
 * 
 * @author Matthias Zeimer
 * @version 1
 * @since 0.1, 04.06.2013
 */
public class UnmodifiableTimestamp //
        extends TechnicalValue<UnmodifiableTimestamp> {

    /**
     * The serial version UID for serialisation support.
     * 
     * @see Serializable
     */
    private static final long serialVersionUID = -4276905380465047254L;

    /**
     * @return
     */
    private static XMLGregorianCalendar createXMLCalendar(final long timestamp) {
        final GregorianCalendar calendar = new GregorianCalendar(TimeZone
                .getTimeZone("UTC"));
        calendar.setTime(new Date(timestamp));
        try {
            return DatatypeFactory.newInstance().newXMLGregorianCalendar(
                    calendar);
        } catch (final DatatypeConfigurationException cause) {
            throw new RuntimeException("Failed to create date representation",
                    cause);
        }
    }

    private final long timestamp;

    public static UnmodifiableTimestamp valueOf(Date date) {

        return new UnmodifiableTimestamp(date.getTime());
    }

    /**
     * 
     */
    private UnmodifiableTimestamp(final long timestamp) {
        super("%s", createXMLCalendar(timestamp).toXMLFormat());

        this.timestamp = timestamp;
    }

    public Date toDate() {
        return new Date(this.timestamp);
    }
}
